package system.task.quartz;

import system.task.ExecutorContext;
import system.task.TaskExecutor;
import system.task.TaskLogger;
import system.task.errors.TaskException;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 外部执行任务
 */
public class ExecJob implements TaskExecutor {
    private final String path;

    public ExecJob(String path) {
        this.path = path;
    }

    @Override
    public void run(ExecutorContext context) throws Exception {
        Map<String, Object> param = context.getParam();
        TaskLogger logger = context.getLogger();

        //
        Process process;
        if (param.size() == 0) {
            process = Runtime.getRuntime().exec(this.path);
        } else {

            List<String> list = new ArrayList<>();
            list.add(this.path);
            for (String k : param.keySet()) {
                Object v = param.get(k);
                if (v == null) {
                    list.add("--" + k);
                } else if ("".equals(v)) {
                    list.add("--" + k + "=");
                } else {
                    list.add("--" + k + "=" + String.valueOf(v));
                }
            }

            process = Runtime.getRuntime().exec(list.toArray(new String[0]));
        }

        String line;

        //
        try (BufferedReader inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            while ((line = inputReader.readLine()) != null) {
                // 处理输入流内容
                logger.writeln(line);
            }
        }

        //
        try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
            while ((line = errorReader.readLine()) != null) {
                logger.error(line);
            }
        }

        //
        while (process.waitFor(60, TimeUnit.SECONDS)) {
            // 子进程已完成
            int exitCode = process.exitValue();
            if (exitCode == 0) break;
            throw new TaskException("Task run error, exit code: " + exitCode);
        }

    }
}
